export {}

/* 
  类装饰器
  属性装饰器
  方法装饰器
  访问器装饰器
  参数装饰器


  类装饰器
    - 参数：
        1. 被装饰的类

    - 作用：
        - 修改类
    
    - 修改方式：
        1.直接修改，通过类直接对其进行修改
          - 通过装饰器添加的属性无法直接访问
        2.返回一个新的类，替换旧的类
          - 新的类必须得是旧类的子类
*/

function render(target: Function) {
  const oldRender = target.prototype.render

  target.prototype.render = function () {
    return `<h1>${oldRender.apply(this)}</h1>`
  }
}

function deco(target: Function) {
  target.prototype.age = 18
}

function deco2<T extends { new (...args: any[]): any }>(target: T) {
  return class extends target {
    render() {
      return `<h1>${super.render()}</h1>`
    }
  }
}

@deco2
class Person {
  constructor(public name: string) {}

  render() {
    return this.name
  }
}

// console.log(Person)

const p = new Person("孙悟空")
console.log(p.render())


// console.log((p as any).age)

// function Component(target: Function) {
//   target.prototype.selector = "my-news"
//   target.prototype.template = "<h1>今天天气真不错！</h1>"
// }

// 装饰器工厂，一个返回装饰器的函数
function Component(options: { selector: string; template: string }) {
  return function (target: Function) {
    target.prototype.selector = options.selector
    target.prototype.template = options.template
  }
}

/* 
  selector <my-news />
  template <h1>今天天气真不错！</h1>
*/
@Component({
  selector: "news",
  template: "<p>今天天气真不错！<p>",
})
class News {
  constructor(public title: string) {}
}
